/*****************************************************************************
 *   Copyright 2005 Tim A Wang
 *
 *   Licensed under the Apache License, Version 2.0 (the "License");
 *   you may not use this file except in compliance with the License.
 *   You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 *   Unless required by applicable law or agreed to in writing, software
 *   distributed under the License is distributed on an "AS IS" BASIS,
 *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *   See the License for the specific language governing permissions and
 *   limitations under the License.
 *
 ****************************************************************************/
package com.jb.web.bean;

import com.jb.faces.el.AttributeEvaluator;
import com.jb.web.bean.inspector.BackgroundPropertyEditor;
import com.jb.web.bean.inspector.BorderPropertyEditor;
import com.jb.web.bean.inspector.FontPropertyEditor;
import com.jb.web.bean.inspector.OptionPropertyEditor;
import com.jb.web.context.WebContext;
import com.jb.web.model.css.Style;

import java.util.Hashtable;
import java.util.Iterator;

import javax.servlet.jsp.el.ELException;


public class HtmlItem extends UIComponentImpl {
    static final long serialVersionUID = 123123L;

    static {
        publish(HtmlItem.class, STYLE, "width");
        publish(HtmlItem.class, STYLE, "height");
        publish(HtmlItem.class, STYLE, "floatStyle",new OptionPropertyEditor("seeded:floatStyle"));
        publish(HtmlItem.class, STYLE, "fontStyle", new FontPropertyEditor());
/*        //width of the component

        //css style

        //called when prepare view is called
        publish(HtmlItem.class, EVENT_HANDLER, "onUpdateView");

        //Set of event handler that can be assigned to a number of components
        //see com.jb.web.style.EventSet
        //for more details
        //publish(HtmlItem.class, EVENT_HANDLER, "eventSet");
        //java script event handler
*/
        publish(HtmlItem.class, JS_HANDLER, "onClick");
        publish(HtmlItem.class, JS_HANDLER, "onDblClick");

        publish(HtmlItem.class, JS_HANDLER, "onMouseOut");
        publish(HtmlItem.class, JS_HANDLER, "onMouseOver");
        publish(HtmlItem.class, JS_HANDLER, "onMouseDown");
        publish(HtmlItem.class, JS_HANDLER, "onMouseUp");

        publish(HtmlItem.class, STYLE, "backgroundStyle", new BackgroundPropertyEditor());
        publish(HtmlItem.class, STYLE, "borderStyle", new BorderPropertyEditor());
        publish(HtmlItem.class, STYLE, "displayStyle", new OptionPropertyEditor("seeded:displayStyle"));
        publish(HtmlItem.class, GENERAL, "visible");
        publish(HtmlItem.class, STYLE, "cursor", new OptionPropertyEditor("seeded:cursor"));
        publish(HtmlItem.class, STYLE, "styleClass");
        publish(HtmlItem.class, EVENT_HANDLER, "onUpdateView");
    }

    //Static methods for property editors
    static Hashtable propertyRegistor = new Hashtable();
    protected String backgroundStyle; //publish
    protected String fontStyle;
    protected String displayStyle; //publish
    protected String styleClass; //publish
    private String borderStyle; //=new BorderStyle();
    private String cursor; //=new cursor style();
    
    private String floatStyle;//floating style, left, right, and default
    //dimension
    private String height; //publish
    private String onClick;//on click event
    private String onDblClick; //on dbl click event
    private String onMouseDown; 
    private String onMouseOut;
    private String onMouseOver;
    private String onMouseUp;
    
    private String width; //publish
    private String title;

    public void setBackgroundStyle(String backgroundStyle) {
        this.backgroundStyle = backgroundStyle;
    }

    public String getBackgroundStyle() {
        return (backgroundStyle == null) ? "" : backgroundStyle;
    }

    public void setBorderStyle(String borderStyle) {
        this.borderStyle = borderStyle;
    }

    public String getBorderStyle() {
        return (borderStyle == null) ? "" : borderStyle;
    }

    public HtmlItem getChildByNameType(String pName, Class pClass) {
        Iterator c = this.getChildren().iterator();

        while (c.hasNext()) {
            HtmlItem child = (HtmlItem)c.next();

            if (pClass.isInstance(child) && child.getId().equals(pName)) {
                return child;
            }
        }

        return null;
    }

    /**
     * DOCUMENT ME!
     *
     * @param cursor DOCUMENT ME!
     */
    public void setCursor(String cursor) {
        this.cursor = cursor;
    }

    /**
     * Gets cursor style.
     *
     * @return cursor style.
     */
    public String getCursor() {
        return cursor;
    }

    /**
     * Gets dimension style.
     *
     * @return dimension style.
     */
    public String getDimensionStyle() {
        return Style.addProperty("width", getWidth(), null) + 
            Style.addProperty("height", getHeight(), null);
    }

    /**
     * Sets display style. None, Inline, Block, etc.
     *
     * @param displayStyle now display style.
     */
    public void setDisplayStyle(String displayStyle) {
        this.displayStyle = displayStyle;
    }
    /**
     * Returns display style per set method.
     * @return display style.
     */
    public String getDisplayStyle() {
        return this.displayStyle;
    }
    /**
     * Returns its display style. Style is in CSS format.
     *
     * @param ctx the runtime context
     *
     * @return CSS style for display.
     */
    public String getDisplayStyle(WebContext ctx) {
        if ((displayStyle == null) || (displayStyle.length() == 0)
            ||(!ctx.isRunTime() && isDesignable() && displayStyle.equalsIgnoreCase("none"))//show when design
        ) {
            return "";
        }

        return "display:" + displayStyle + ";";
    }

    public void setFloatStyle(String floatStyle) {
        this.floatStyle = floatStyle;
    }

    public String getFloatStyle() {
        return floatStyle;
    }

    /**
     * Sets component height.
     *
     * @param height the new height.
     */
    public void setHeight(String height) {
        this.height = height;
    }

    /**
     * DOCUMENT ME!
     *
     * @return DOCUMENT ME!
     */
    public String getHeight() {
        return height;
    }

    //java script events

    public void setOnClick(String onClick) {
        this.onClick = onClick;
    }

    /**
     * DOCUMENT ME!
     *
     * @return DOCUMENT ME!
     */
    public String getOnClick() {
        return onClick;
    }

    /**
     * DOCUMENT ME!
     *
     * @param onDblClick DOCUMENT ME!
     */
    public void setOnDblClick(String onDblClick) {
        this.onDblClick = onDblClick;
    }

    /**
     * DOCUMENT ME!
     *
     * @return DOCUMENT ME!
     */
    public String getOnDblClick() {
        return onDblClick;
    }

    /**
     * DOCUMENT ME!
     *
     * @param onMouseDown DOCUMENT ME!
     */
    public void setOnMouseDown(String onMouseDown) {
        this.onMouseDown = onMouseDown;
    }

    /**
     * DOCUMENT ME!
     *
     * @return DOCUMENT ME!
     */
    public String getOnMouseDown() {
        return onMouseDown;
    }

    /**
     * DOCUMENT ME!
     *
     * @param onMouseOut DOCUMENT ME!
     */
    public void setOnMouseOut(String onMouseOut) {
        this.onMouseOut = onMouseOut;
    }

    /**
     * DOCUMENT ME!
     *
     * @return DOCUMENT ME!
     */
    public String getOnMouseOut() {
        return onMouseOut;
    }

    /**
     * DOCUMENT ME!
     *
     * @param onMouseOver DOCUMENT ME!
     */
    public void setOnMouseOver(String onMouseOver) {
        this.onMouseOver = onMouseOver;
    }

    /**
     * DOCUMENT ME!
     *
     * @return DOCUMENT ME!
     */
    public String getOnMouseOver() {
        return onMouseOver;
    }

    /**
     * DOCUMENT ME!
     *
     * @param onMouseUp DOCUMENT ME!
     */
    public void setOnMouseUp(String onMouseUp) {
        this.onMouseUp = onMouseUp;
    }

    /**
     * Return event handler for mouse up event
     *
     * @return mouse up event handler.
     */
    public String getOnMouseUp() {
        return onMouseUp;
    }

    /**
     * Returns css string for this component
     *
     * @param ctx web context for the request.
     *
     * @return css style string.
     */
    public String getStyle(WebContext ctx) {
        String style = 
            getDisplayStyle(ctx) + getBorderStyle() + getBackgroundStyle() + 
            getDimensionStyle() + getFontStyle() +
            Style.addProperty("cursor", getCursor(), null) + 
            Style.addProperty("float", getFloatStyle(), null);

        try {
            return (String)AttributeEvaluator.evaluate(ctx, this, style);
        } catch (ELException e) {
            return style;
        }
    }
    
    /**
     * Sets style class name.
     * @param newClass class name.
     */
    public void setStyleClass(String newClass) {
        styleClass = newClass;
    }
    /**
     * returns css class name.
     * @return class name.
     */
    public String getStyleClass() {
        return styleClass;
    }

    public String getStyleClass(WebContext ctx) {
        try {
            if ((styleClass == null) || (styleClass.length() == 0)) {
                return "";
            }
            return (String)AttributeEvaluator.evaluate(ctx, this,styleClass);
        } catch (ELException e) {
            return styleClass;
        }
    }

    public void setWidth(String newWidth) {
        width = newWidth;
    }

    public String getWidth() {
        return width;
    }

    protected static void registerProperty(Class pClass, String propName) {
        propertyRegistor.put(pClass.getName() + "." + propName, propName);
    }

    protected boolean isPropertyEditable(String propName) {
        return isPropertyEditable(this.getClass(), propName);
    }

    static boolean isPropertyEditable(Class pClass, String propName) {
        return propertyRegistor.get(pClass.getName() + "." + propName) != null;
    }


    public void setFontStyle(String newFont) {
        fontStyle = newFont;
    }

    public String getFontStyle() {
        return (fontStyle == null) ? "" : fontStyle;
    }

    public void setTitle(String param) {
        this.title = param;
    }

    public String getTitle() {
        return title;
    }
}
